﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace editor.app
{
    /// <summary>
    /// KFAnim.xaml 的交互逻辑
    /// </summary>
    public partial class RKFAnim : UserControl, IResEditControl
    {
        comm.objst.RPack _rpack = null;
        comm.objst.RKeyFrameAnim _kfanim = null;
        string _kfanimResKey = "";
        string _threadId = "";
        Button _lastBtn = null;

        public RKFAnim(comm.objst.RPack rpack, string kfanimResKey)
        {
            InitializeComponent();

            _kfanimResKey = kfanimResKey;
            _rpack = rpack;
            _kfanim = _rpack.GetResource<comm.objst.RKeyFrameAnim>(kfanimResKey);

            cbImageKeys.Items.Clear();
            var keys = _rpack.GetAllResourceKeys(typeof(comm.objst.RImage));
            foreach (var key in keys)
            {
                var rimage = _rpack.GetResource<comm.objst.RImage>(key);
                cbImageKeys.Items.Add(new TextBlock { Text = rimage.Name, Tag = key });
            }
            if (cbImageKeys.Items.Count > 0)
            {
                cbImageKeys.SelectedIndex = 0;
            }

            FillImage();
            Fill();

            gridPlayMask.Visibility = Visibility.Collapsed;
            gridImage.Visibility = Visibility.Collapsed;

            kfAnimImage.OnCloseCallback = () =>
            {
                gridImage.Visibility = Visibility.Collapsed;
                Fill();
            };

            Unloaded += new RoutedEventHandler(RKFAnim_Unloaded);
            btnPlay.Click += new RoutedEventHandler(btnPlay_Click);
            btnNewImage.Click += new RoutedEventHandler(btnNewImage_Click);
            btnStop.Click += new RoutedEventHandler(btnStop_Click);
            btnNewImages.Click += new RoutedEventHandler(btnNewImages_Click);
            btnClearImages.Click += new RoutedEventHandler(btnClearImages_Click);
            tbSetAllTime.TextChanged += new TextChangedEventHandler(tbSetAllTime_TextChanged);
        }

        void tbSetAllTime_TextChanged(object sender, TextChangedEventArgs e)
        {
            uint t = 0;
            if (uint.TryParse(tbSetAllTime.Text.Trim(), out t))
            {
                for (int i = 0, len = _kfanim.TimeList.Count; i < len; i++)
                {
                    _kfanim.TimeList[i] = t;
                }
            }
            FillFrame();
        }
        void btnClearImages_Click(object sender, RoutedEventArgs e)
        {
            _kfanim.ImageDic.Clear();
            FillImage();
        }
        void RKFAnim_Unloaded(object sender, RoutedEventArgs e)
        {
            comm.ThreadHelper.Stop(_threadId);
        }
        void btnStop_Click(object sender, RoutedEventArgs e)
        {
            gridPlayMask.Visibility = Visibility.Collapsed;
            comm.ThreadHelper.Stop(_threadId);
        }
        void btnPlay_Click(object sender, RoutedEventArgs e)
        {
            gridPlayMask.Visibility = Visibility.Visible;
            wpPlay.Children.Clear();
            foreach (var key in _kfanim.ImageDic.Keys)
            {
                var image = _kfanim.ImageDic[key];
                var kfanimView = new RKFAnimView { Margin = new Thickness(0, 0, 20, 20) };
                kfanimView.Load(_rpack, _kfanimResKey, key);
                wpPlay.Children.Add(kfanimView);
            }
            var mainTl = new comm.MainTimeline();
            var line = new comm.Timeline(_kfanim.TimeList.ToArray());
            line.OnEnterTimeCallback = l =>
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    foreach (var el in wpPlay.Children)
                    {
                        var view = (RKFAnimView)el;
                        view.EnterFrame(l.TimeIndex);
                    }
                }));
            };
            mainTl.AddLine("line1", line);
            mainTl.Begin();

            _threadId = comm.ThreadHelper.Run(() =>
            {
                while (true)
                {
                    mainTl.Update();
                    Thread.Sleep(1);
                }
            });
        }
        void btnNewImage_Click(object sender, RoutedEventArgs e)
        {
            if (cbImageKeys.SelectedIndex != -1)
            {
                var guid = comm.GUID.NewString();
                _kfanim.ImageDic.Add(guid, new comm.objst.RKeyFrameAnim.Image
                {
                    Name = guid,
                    ResKey = ((TextBlock)cbImageKeys.SelectedValue).Tag.ToString(),
                });
                FillImage();
            }
        }
        void btnNewImages_Click(object sender, RoutedEventArgs e)
        {
            if (cbImageKeys.SelectedIndex != -1)
            {
                var types = comm.objst.DObject.Data.GetDirTypes();
                foreach (var type in types)
                {
                    var guid = comm.GUID.NewString();
                    _kfanim.ImageDic.Add(guid, new comm.objst.RKeyFrameAnim.Image
                    {
                        Name = type,
                        ResKey = ((TextBlock)cbImageKeys.SelectedValue).Tag.ToString(),
                    });
                }
                tbTotalTime.Text = "TotalTime:" + _kfanim.GetTotalTime();
                FillImage();
            }
        }
        void btnDelImage_Click(object sender, RoutedEventArgs e)
        {
            var btn = (Button)sender;
            var parent = (FrameworkElement)btn.Parent;
            var key = parent.Tag.ToString();
            if (_kfanim.ImageDic.ContainsKey(key))
            {
                _kfanim.ImageDic.Remove(key);
            }
            Fill();
        }
        void textboxImage_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textbox = (TextBox)sender;
            var parent = (FrameworkElement)textbox.Parent;
            var key = parent.Tag.ToString();
            if (_kfanim.ImageDic.ContainsKey(key))
            {
                var item = _kfanim.ImageDic[key];
                item.Name = textbox.Text;
            }
        }
        void btnEditImage_Click(object sender, RoutedEventArgs e)
        {
            var btn = (Button)sender;
            var parent = (FrameworkElement)btn.Parent;
            var key = parent.Tag.ToString();
            if (_kfanim.ImageDic.ContainsKey(key))
            {
                gridImage.Visibility = Visibility.Visible;
                kfAnimImage.Load(_rpack, _kfanimResKey, key);
                try
                {
                    _lastBtn.Background = null;
                }
                catch (Exception)
                {
                }
                _lastBtn = btn;
                _lastBtn.Background = new SolidColorBrush(Color2.Black(30));
            }
        }
        void textboxTime_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textbox = (TextBox)sender;
            var ix = (int)textbox.Tag;
            uint time = 0;
            if (uint.TryParse(textbox.Text, out time))
            {
                _kfanim.TimeList[ix] = time;
                tbTotalTime.Text = "TotalTime:" + _kfanim.GetTotalTime();
            }
        }

        void FillImage()
        {
            spImage.Children.Clear();
            foreach (var key in _kfanim.ImageDic.Keys)
            {
                var item = _kfanim.ImageDic[key];
                var rimage = _rpack.GetResource<comm.objst.RImage>(item.ResKey);
                var grid = new Grid { Tag = key, Margin = new Thickness(0, 4, 0, 0) };

                if (rimage == null)
                {
                    grid.Opacity = .5;
                }

                #region textbox
                var textbox = new TextBox
                {
                    Text = item.Name,
                    FontSize = 12,
                    BorderThickness = new Thickness(0),
                    Margin = new Thickness(20, 0, 60, 0),
                    VerticalAlignment = VerticalAlignment.Center
                };
                textbox.TextChanged += new TextChangedEventHandler(textboxImage_TextChanged);
                #endregion

                #region btnDel
                var btnDel = new Button
                {
                    Content = "X",
                    Focusable = false,
                    Width = 20,
                    Height = 24,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Center
                };
                btnDel.Click += new RoutedEventHandler(btnDelImage_Click);
                #endregion

                #region btnEdit
                var btnEdit = new Button
                {
                    Tag = item.Name,
                    Content = "E(" + item.FrameList.Count + ")",
                    Focusable = false,
                    Width = 60,
                    Height = 24,
                    HorizontalAlignment = HorizontalAlignment.Right,
                    VerticalAlignment = VerticalAlignment.Center
                };
                btnEdit.Click += new RoutedEventHandler(btnEditImage_Click);
                #endregion

                grid.Children.Add(textbox);
                grid.Children.Add(btnDel);
                grid.Children.Add(btnEdit);
                spImage.Children.Add(grid);
            }
        }
        void FillFrame()
        {
            gridFrame.Children.Clear();
            gridFrame.ColumnDefinitions.Clear();
            gridFrame.RowDefinitions.Clear();

            int colCount = _kfanim.TimeList.Count + 1,
                rowCount = _kfanim.ImageDic.Count + 1;

            for (int i = 0; i < colCount; i++)
            {
                gridFrame.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0, GridUnitType.Auto) });
            }
            for (int i = 0; i < rowCount; i++)
            {
                gridFrame.RowDefinitions.Add(new RowDefinition { Height = new GridLength(0, GridUnitType.Auto) });
            }

            var col = 0;
            foreach (var time in _kfanim.TimeList)
            {
                var textbox = new TextBox
                {
                    Tag = col,
                    Text = time.ToString(),
                    Width = 60,
                    Height = 24,
                    Margin = new Thickness(2),
                    HorizontalAlignment = HorizontalAlignment.Left
                };
                textbox.SetValue(Grid.ColumnProperty, col + 1);
                textbox.SetValue(Grid.RowProperty, 0);
                textbox.TextChanged += new TextChangedEventHandler(textboxTime_TextChanged);

                gridFrame.Children.Add(textbox);
                col++;
            }

            var imageDic = new Dictionary<string, BitmapImage>();

            var rowIndex = 1;
            foreach (var key in _kfanim.ImageDic.Keys)
            {
                var image = _kfanim.ImageDic[key];
                var rimage = _rpack.GetResource<comm.objst.RImage>(image.ResKey);
                if (rimage != null && rimage.ImageBytes != null && !imageDic.ContainsKey(image.ResKey))
                {
                    var bitmap = new BitmapImage();
                    bitmap.FromBytes(rimage.ImageBytes);
                    imageDic.Add(image.ResKey, bitmap);
                }

                var tbKey = new TextBlock
                {
                    Text = image.Name,
                    Margin = new Thickness(2),
                    VerticalAlignment = VerticalAlignment.Center,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    Foreground = new SolidColorBrush(Color2.White())
                };
                tbKey.SetValue(Grid.ColumnProperty, 0);
                tbKey.SetValue(Grid.RowProperty, rowIndex);
                gridFrame.Children.Add(tbKey);

                var col2 = 0;
                foreach (var index in image.FrameList)
                {
                    if (rimage != null)
                    {
                        var cv = RImage.GetFrameCanvas(_rpack, image.ResKey, index, imageDic[image.ResKey]);
                        cv.Margin = new Thickness(2);
                        cv.SetValue(Grid.ColumnProperty, col2 + 1);
                        cv.SetValue(Grid.RowProperty, rowIndex);
                        gridFrame.Children.Add(cv);
                    }
                    col2++;
                }
                rowIndex++;
            }
        }
        void Fill()
        {
            _kfanim.TrimTimeList();

            FillImage();
            FillFrame();
            tbTotalTime.Text = _kfanim.GetTotalTime() + "ms";
        }

        public void Reload()
        {
            Fill();
        }
        public string GetResKey()
        {
            return _kfanimResKey;
        }
    }
}
